package com.kantboot.api.yrapi.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.digest.MD5;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.kantboot.api.yrapi.util.entity.YrApiCheckEntity;
import com.kantboot.api.yrapi.util.entity.YrApiParamEntity;
import com.kantboot.api.yrapi.util.entity.YrApiRechargeParam;
import com.kantboot.api.yrapi.util.entity.YrApiRequestEntity;
import com.kantboot.util.common.exception.BaseException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;

import java.util.*;

/**
 * 大猿人api的工具类
 * @author 方某方
 */
@Slf4j
public class YrApiUtil {

    /**
     * 生成请求参数
     * @param param 参数
     * @param yrApiParamEntity 大猿人api的参数
     * @return 请求参数
     */
    public static String createRequestParam(Object param, YrApiParamEntity yrApiParamEntity){
        String yrApiUserId = yrApiParamEntity.getYrApiUserId();
        String yrApiAppKey = yrApiParamEntity.getYrApiAppKey();
        // 将param转换成map，并且将驼峰式转换成下划线，同时将值为null的属性去掉
        Map<String,Object> map = BeanUtil.beanToMap(param,true,true);
        if(map==null){
            map = new HashMap<>();
        }
        // 添加userid
        map.put("userid",yrApiUserId);
        // 将map转换成key=value&key=value的形式
        Set<String> strings = map.keySet();
        // 将set转换为List
        ArrayList<String> keyList = new ArrayList<>(strings);
        // 按照字典排序
        keyList.sort(String::compareTo);

        // 拼接字符串
        StringBuilder stringBuilder = new StringBuilder();
        for (String string : keyList) {
            if (map.get(string) == null) {
                continue;
            }
            stringBuilder.append(string).append("=").append(map.get(string)).append("&");
        }
        String result = stringBuilder.toString();

        // 添加appKey
        stringBuilder.append("apikey=").append(yrApiAppKey);
        // 生成签名的字符串
        String paramStr = stringBuilder.toString();
        // 生成签名
        String sign = MD5.create().digestHex(paramStr).toUpperCase();
        // 将sign添加到entityParam中
        result+="sign="+sign;
        // 返回
        return result;
    }

    /**
     * 发送请求
     * @param entity 请求实体
     * @param yrApiParamEntity 大猿人api的参数
     * @return 请求结果
     */
    @SneakyThrows
    public static Object sendRequest(YrApiRequestEntity entity, YrApiParamEntity yrApiParamEntity) {
        String yrApiUrlPrefix = yrApiParamEntity.getYrApiUrlPrefix();
        Object param = entity.getParam();
        // 如果yrApiUrlPrefix结尾不是/，则加上/
        yrApiUrlPrefix = yrApiUrlPrefix.endsWith("/") ? yrApiUrlPrefix : yrApiUrlPrefix + "/";
        // 如果uri以/开头，则去掉/
        String uri = entity.getUri().startsWith("/") ? entity.getUri().substring(1) : entity.getUri();
        // 拼接url
        String url = yrApiUrlPrefix + uri;

        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, createRequestParam(entity.getParam(), yrApiParamEntity));
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .addHeader("content-type", "application/x-www-form-urlencoded")
                .build();

        Response response = client.newCall(request).execute();
        String requestResult = response.body().string();
        log.info("请求yrApi的结果:{}",requestResult);

        JSONObject jsonObject = JSON.parseObject(requestResult);
        if(jsonObject.getInteger("errno")!=0){
            throw BaseException.of("yrApiErrorOf"+jsonObject.getInteger("errno"),jsonObject.getString("errmsg"));
        }
        return jsonObject.getList("data", Object.class);
    }

    /**
     * 充值
     * @param param 参数
     * @param yrApiParamEntity 大猿人api的参数
     * @return 请求结果
     */
    public static void recharge(YrApiRechargeParam param, YrApiParamEntity yrApiParamEntity) {
        YrApiRequestEntity entity = new YrApiRequestEntity()
                .setUri("/index/recharge")
                .setParam(param);
        sendRequest(entity, yrApiParamEntity);
    }

    /**
     * 订单号查询
     * @param outTradeNumList 订单号列表
     * @param yrApiParamEntity 大猿人api的参数
     * @return 查询结果
     */
    public static List<YrApiCheckEntity> check(List<String> outTradeNumList, YrApiParamEntity yrApiParamEntity) {
        YrApiRequestEntity entity = new YrApiRequestEntity()
                .setUri("/index/check")
                .setParam(Map.of("out_trade_nums", String.join(",", outTradeNumList)));
        Object obj = sendRequest(entity, yrApiParamEntity);
        JSONArray objects = JSON.parseArray(JSON.toJSONString(obj));

        // 将objects转为List<YrApiCheckEntity>,并且下划线转为驼峰式
        return JSON.parseArray(JSON.toJSONString(objects), YrApiCheckEntity.class);
    }

    public static void main(String[] args) {
        YrApiParamEntity yrApiParamEntity = new YrApiParamEntity()
                .setYrApiUrlPrefix("http://api.dayuanren.vip/yrapi.php/")
                .setYrApiUserId("917")
                .setYrApiAppKey("E16sqe2fSIdWCcQuBDz3OVyRKGF5YjN7");
        YrApiRechargeParam param = new YrApiRechargeParam()
                .setMobile("15180370648")
                .setProductId(1217L)
                .setOutTradeNum(5l)
                .setNotifyUrl("http://www.baidu.com");
        recharge(param, yrApiParamEntity);
    }

}
